import pygame
import json
import os
from typing import Dict, Any, Optional, Tuple


class CardDisplay:
    """卡牌显示类"""
    
    def __init__(self, screen_width: int = 1200, screen_height: int = 900):
        self.screen_width = screen_width
        self.screen_height = screen_height
        
        # 卡牌尺寸
        self.card_width = 100  # 减小卡牌宽度（原120）
        self.card_height = 140  # 减小卡牌高度（原160）
        
        # 字体
        pygame.font.init()
        self.title_font = pygame.font.Font(None, 20)
        self.stats_font = pygame.font.Font(None, 24)
        self.small_font = pygame.font.Font(None, 16)
        
        # 颜色
        self.colors = {
            'white': (255, 255, 255),
            'black': (0, 0, 0),
            'red': (255, 0, 0),
            'green': (0, 255, 0),
            'blue': (0, 0, 255),
            'yellow': (255, 255, 0),
            'gray': (128, 128, 128),
            'dark_gray': (64, 64, 64),
            'light_gray': (192, 192, 192),
            'brown': (139, 69, 19),
            'purple': (128, 0, 128)
        }
        
        # 加载卡牌注册表
        self.card_registry = self._load_card_registry()
        
        # 卡牌图片缓存
        self.card_images = {}
        self._load_card_images()
    
    def _load_card_registry(self) -> Dict[str, Any]:
        """加载卡牌注册表"""
        try:
            # 获取当前文件所在目录的父目录
            import os
            current_dir = os.path.dirname(os.path.abspath(__file__))
            client_dir = os.path.dirname(current_dir)
            registry_path = os.path.join(client_dir, "card_registry.json")
            
            with open(registry_path, "r", encoding="utf-8") as f:
                return json.load(f)
        except Exception as e:
            print(f"Failed to load card registry: {e}")
            return {}
    
    def _load_card_images(self):
        """加载卡牌图片"""
        for card_id, card_data in self.card_registry.items():
            image_path = card_data.get("image_path", "")
            
            # 获取正确的图片路径
            import os
            current_dir = os.path.dirname(os.path.abspath(__file__))
            client_dir = os.path.dirname(current_dir)
            full_image_path = os.path.join(client_dir, image_path)
            
            if os.path.exists(full_image_path):
                try:
                    image = pygame.image.load(full_image_path)
                    # 缩放到卡牌尺寸
                    self.card_images[card_id] = pygame.transform.scale(image, (self.card_width, self.card_height))
                except Exception as e:
                    print(f"Failed to load image {full_image_path}: {e}")
                    self.card_images[card_id] = None
            else:
                print(f"Image file not found: {full_image_path}")
                self.card_images[card_id] = None
    
    def draw_card(self, screen: pygame.Surface, card_data: Dict[str, Any], x: int, y: int, 
                  highlighted: bool = False, selected: bool = False) -> pygame.Rect:
        """绘制卡牌"""
        card_rect = pygame.Rect(x, y, self.card_width, self.card_height)
        
        # 1. 先绘制背景
        pygame.draw.rect(screen, self.colors['white'], card_rect)
        
        # 2. 绘制卡牌图片（如果有）- 填满卡牌作为背景
        card_id = card_data.get("card_id", "")
        card_type = card_data.get("type", "")
        
        if card_id in self.card_images and self.card_images[card_id]:
            # 图片填满整个卡牌区域（稍微留出边框空间）
            image_rect = pygame.Rect(x + 2, y + 2, self.card_width - 4, self.card_height - 4)
            scaled_image = pygame.transform.scale(self.card_images[card_id], (image_rect.width, image_rect.height))
            screen.blit(scaled_image, (image_rect.x, image_rect.y))
        
        # 3. 绘制边框
        pygame.draw.rect(screen, self.colors['black'], card_rect, 2)
        
        # 4. 高亮或选中边框（在最上层）
        if highlighted:
            pygame.draw.rect(screen, self.colors['yellow'], card_rect, 5)
        elif selected:
            pygame.draw.rect(screen, self.colors['green'], card_rect, 5)
        
        # 5. 卡牌名称背景（半透明效果）
        name_bg = pygame.Surface((self.card_width, 30))
        name_bg.set_alpha(200)  # 半透明
        name_bg.fill(self.colors['light_gray'])
        screen.blit(name_bg, (x, y))
        
        # 6. 卡牌名称
        name = card_data.get("name", "")
        name_text = self.small_font.render(name, True, self.colors['black'])
        name_rect = name_text.get_rect(center=(x + self.card_width // 2, y + 15))
        screen.blit(name_text, name_rect)
        
        # 根据卡牌类型绘制不同信息
        # card_type 在上面图片渲染时已获取，这里需要确保可以访问
        if card_type == "Summoner":
            # 召唤师只显示HP
            hp = card_data.get("hp", 0)
            
            # HP背景圆圈
            hp_center = (x + self.card_width // 2, y + self.card_height - 20)
            pygame.draw.circle(screen, self.colors['white'], hp_center, 20)
            pygame.draw.circle(screen, self.colors['black'], hp_center, 20, 2)
            
            hp_text = self.stats_font.render(str(hp), True, self.colors['red'])
            hp_rect = hp_text.get_rect(center=hp_center)
            screen.blit(hp_text, hp_rect)
        
        elif card_type == "Champion":
            # Champion显示花费、攻击、HP
            cost = card_data.get("cost", 0)
            attack = card_data.get("attack", 0)
            hp = card_data.get("hp", 0)
            
            # 花费（左上角）- 蓝色圆圈
            cost_center = (x + 8, y + 8)
            pygame.draw.circle(screen, self.colors['blue'], cost_center, 12)
            pygame.draw.circle(screen, self.colors['white'], cost_center, 12, 2)
            cost_text = self.stats_font.render(str(cost), True, self.colors['white'])
            cost_rect = cost_text.get_rect(center=cost_center)
            screen.blit(cost_text, cost_rect)
            
            # 攻击力（左下角）- 红色圆圈
            attack_center = (x + 8, y + self.card_height - 8)
            pygame.draw.circle(screen, self.colors['red'], attack_center, 12)
            pygame.draw.circle(screen, self.colors['white'], attack_center, 12, 2)
            attack_text = self.stats_font.render(str(attack), True, self.colors['white'])
            attack_rect = attack_text.get_rect(center=attack_center)
            screen.blit(attack_text, attack_rect)
            
            # HP（右下角）- 绿色圆圈
            hp_center = (x + self.card_width - 8, y + self.card_height - 8)
            pygame.draw.circle(screen, self.colors['green'], hp_center, 12)
            pygame.draw.circle(screen, self.colors['white'], hp_center, 12, 2)
            hp_text = self.stats_font.render(str(hp), True, self.colors['white'])
            hp_rect = hp_text.get_rect(center=hp_center)
            screen.blit(hp_text, hp_rect)
            
            # 特殊状态指示
            if card_data.get("is_hidden", False):
                # Assassin隐身状态
                hidden_text = self.small_font.render("Hidden", True, self.colors['purple'])
                screen.blit(hidden_text, (x + 5, y + 25))
            
            if card_data.get("guarding_target_id"):
                # Guard守卫状态
                guard_text = self.small_font.render("Guarding", True, self.colors['brown'])
                screen.blit(guard_text, (x + 5, y + 40))
        
        elif card_type == "Item":
            # Item显示花费和效果描述
            cost = card_data.get("cost", 0)
            description = card_data.get("description", "")
            
            # 花费（左上角）
            cost_text = self.stats_font.render(str(cost), True, self.colors['blue'])
            screen.blit(cost_text, (x + 5, y + 5))
            
            # 效果描述（底部）
            # 将描述分行显示
            words = description.split()
            lines = []
            current_line = ""
            for word in words:
                if len(current_line + " " + word) <= 15:  # 每行最多15个字符
                    current_line += " " + word if current_line else word
                else:
                    if current_line:
                        lines.append(current_line)
                    current_line = word
            if current_line:
                lines.append(current_line)
            
            # 显示描述（最多3行）
            for i, line in enumerate(lines[:3]):
                desc_text = self.small_font.render(line, True, self.colors['black'])
                screen.blit(desc_text, (x + 5, y + self.card_height - 60 + i * 15))
        
        return card_rect
    
    def draw_card_back(self, screen: pygame.Surface, x: int, y: int) -> pygame.Rect:
        """绘制卡牌背面"""
        card_rect = pygame.Rect(x, y, self.card_width, self.card_height)
        
        # 绘制卡牌背面
        pygame.draw.rect(screen, self.colors['dark_gray'], card_rect)
        pygame.draw.rect(screen, self.colors['black'], card_rect, 2)
        
        # 绘制问号
        question_text = self.stats_font.render("?", True, self.colors['white'])
        question_rect = question_text.get_rect(center=card_rect.center)
        screen.blit(question_text, question_rect)
        
        return card_rect
    
    def draw_card_tooltip(self, screen: pygame.Surface, card_data: Dict[str, Any], x: int, y: int):
        """绘制卡牌详细描述提示框"""
        description = card_data.get("description", "")
        if not description:
            return
        
        lines = []
        max_width = 0
        
        # 按 \n 分割文本
        text_lines = description.split('\n')
        # print(f"DEBUG: Split into {len(text_lines)} lines")
        
        # 对每一行进行自动换行处理
        for text_line in text_lines:
            # 如果空行，跳过
            if not text_line.strip():
                continue
                
            words = text_line.split()
            current_line = ""
            
            for word in words:
                if len(current_line + " " + word) <= 25:  # 每行最多25个字符
                    current_line += " " + word if current_line else word
                else:
                    if current_line:
                        lines.append(current_line)
                        max_width = max(max_width, len(current_line))
                    current_line = word
            if current_line:
                lines.append(current_line)
                max_width = max(max_width, len(current_line))
        
        # 提示框尺寸
        tooltip_width = max_width * 8 + 20
        tooltip_height = len(lines) * 20 + 20
        
        # 确保提示框不超出屏幕
        if x + tooltip_width > self.screen_width:
            x = self.screen_width - tooltip_width - 10
        if y + tooltip_height > self.screen_height:
            y = self.screen_height - tooltip_height - 10
        
        # 绘制提示框背景
        tooltip_rect = pygame.Rect(x, y, tooltip_width, tooltip_height)
        pygame.draw.rect(screen, self.colors['black'], tooltip_rect)
        pygame.draw.rect(screen, self.colors['white'], tooltip_rect, 2)
        
        # 绘制描述文本
        for i, line in enumerate(lines):
            text = self.small_font.render(line, True, self.colors['white'])
            screen.blit(text, (x + 10, y + 10 + i * 20))
    
    def get_card_at_position(self, cards: list, mouse_pos: Tuple[int, int], 
                           card_positions: list) -> Optional[Dict[str, Any]]:
        """获取鼠标位置下的卡牌"""
        for i, (card_data, pos) in enumerate(zip(cards, card_positions)):
            if card_data is None:
                continue
            
            card_rect = pygame.Rect(pos[0], pos[1], self.card_width, self.card_height)
            if card_rect.collidepoint(mouse_pos):
                return card_data
        
        return None
